// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.spnetwork;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import se.krka.kahlua.vm.KahluaTable;
import se.krka.kahlua.vm.KahluaTableIterator;
import zombie.Lua.LuaEventManager;
import zombie.Lua.LuaManager;
import zombie.characters.IsoPlayer;
import zombie.core.Core;
import zombie.core.network.ByteBufferWriter;
import zombie.debug.DebugLog;
import zombie.globalObjects.CGlobalObjectNetwork;
import zombie.iso.IsoGridSquare;
import zombie.iso.IsoObject;
import zombie.iso.IsoWorld;
import zombie.iso.objects.IsoWorldInventoryObject;
import zombie.network.GameClient;
import zombie.network.PacketTypes;
import zombie.network.TableNetworkUtils;
import zombie.vehicles.BaseVehicle;
import zombie.vehicles.VehicleManager;

public final class SinglePlayerClient {
    private static final ArrayList<ZomboidNetData> MainLoopNetData = new ArrayList();
    public static final UdpEngine udpEngine = new SinglePlayerClient.UdpEngineClient();
    public static final UdpConnection connection = new UdpConnection(udpEngine);

    public static void addIncoming(short id, ByteBuffer bb) {
        ZomboidNetData zomboidNetData;
        if (bb.remaining() > 2048) {
            zomboidNetData = ZomboidNetDataPool.instance.getLong(bb.remaining());
        } else {
            zomboidNetData = ZomboidNetDataPool.instance.get();
        }

        zomboidNetData.read(id, bb, connection);
        synchronized (MainLoopNetData) {
            MainLoopNetData.add(zomboidNetData);
        }
    }

    public static void update() throws Exception {
        if (!GameClient.bClient) {
            for (short _short = 0; _short < IsoPlayer.numPlayers; _short++) {
                if (IsoPlayer.players[_short] != null) {
                    IsoPlayer.players[_short].setOnlineID(_short);
                }
            }

            synchronized (MainLoopNetData) {
                for (int _int = 0; _int < MainLoopNetData.size(); _int++) {
                    ZomboidNetData zomboidNetData = (ZomboidNetData)MainLoopNetData.get(_int);

                    try {
                        mainLoopDealWithNetData(zomboidNetData);
                    } finally {
                        MainLoopNetData.remove(_int--);
                    }
                }
            }
        }
    }

    private static void mainLoopDealWithNetData(ZomboidNetData zomboidNetData) throws Exception {
        ByteBuffer byteBuffer = zomboidNetData.buffer;

        try {
            PacketTypes.PacketType packetType = (PacketTypes.PacketType)PacketTypes.packetTypes.get(zomboidNetData.type);
            switch (packetType) {
                case ClientCommand:
                    receiveServerCommand(byteBuffer);
                    break;
                case GlobalObjects:
                    CGlobalObjectNetwork.receive(byteBuffer);
                    break;
                case ObjectChange:
                    receiveObjectChange(byteBuffer);
                    break;
                default:
                    throw new IllegalStateException("Unexpected value: " + packetType);
            }
        } finally {
            ZomboidNetDataPool.instance.discard(zomboidNetData);
        }
    }

    private static void delayPacket(int var0, int var1, int var2) {
    }

    private static IsoPlayer getPlayerByID(int _int) {
        return IsoPlayer.players[_int];
    }

    private static void receiveObjectChange(ByteBuffer byteBuffer) {
        byte _byte = byteBuffer.get();
        if (_byte == 1) {
            short short0 = byteBuffer.getShort();
            String string0 = zombie.GameWindow.ReadString(byteBuffer);
            if (Core.bDebug) {
                DebugLog.log("receiveObjectChange " + string0);
            }

            IsoPlayer isoPlayer = getPlayerByID(short0);
            if (isoPlayer != null) {
                isoPlayer.loadChange(string0, byteBuffer);
            }
        } else if (_byte == 2) {
            short short1 = byteBuffer.getShort();
            String string1 = zombie.GameWindow.ReadString(byteBuffer);
            if (Core.bDebug) {
                DebugLog.log("receiveObjectChange " + string1);
            }

            BaseVehicle baseVehicle = VehicleManager.instance.getVehicleByID(short1);
            if (baseVehicle != null) {
                baseVehicle.loadChange(string1, byteBuffer);
            } else if (Core.bDebug) {
                DebugLog.log("receiveObjectChange: unknown vehicle id=" + short1);
            }
        } else if (_byte == 3) {
            int int0 = byteBuffer.getInt();
            int int1 = byteBuffer.getInt();
            int int2 = byteBuffer.getInt();
            int int3 = byteBuffer.getInt();
            String string2 = zombie.GameWindow.ReadString(byteBuffer);
            if (Core.bDebug) {
                DebugLog.log("receiveObjectChange " + string2);
            }

            IsoGridSquare isoGridSquare0 = IsoWorld.instance.CurrentCell.getGridSquare(int0, int1, int2);
            if (isoGridSquare0 == null) {
                delayPacket(int0, int1, int2);
                return;
            }

            for (int int4 = 0; int4 < isoGridSquare0.getWorldObjects().size(); int4++) {
                IsoWorldInventoryObject isoWorldInventoryObject = (IsoWorldInventoryObject)isoGridSquare0.getWorldObjects().get(int4);
                if (isoWorldInventoryObject.getItem() != null && isoWorldInventoryObject.getItem().getID() == int3) {
                    isoWorldInventoryObject.loadChange(string2, byteBuffer);
                    return;
                }
            }

            if (Core.bDebug) {
                DebugLog.log("receiveObjectChange: itemID=" + int3 + " is invalid x,y,z=" + int0 + "," + int1 + "," + int2);
            }
        } else {
            int int5 = byteBuffer.getInt();
            int int6 = byteBuffer.getInt();
            int int7 = byteBuffer.getInt();
            int int8 = byteBuffer.getInt();
            String string3 = zombie.GameWindow.ReadString(byteBuffer);
            if (Core.bDebug) {
                DebugLog.log("receiveObjectChange " + string3);
            }

            IsoGridSquare isoGridSquare1 = IsoWorld.instance.CurrentCell.getGridSquare(int5, int6, int7);
            if (isoGridSquare1 == null) {
                delayPacket(int5, int6, int7);
                return;
            }

            if (int8 >= 0 && int8 < isoGridSquare1.getObjects().size()) {
                IsoObject isoObject = isoGridSquare1.getObjects().get(int8);
                isoObject.loadChange(string3, byteBuffer);
            } else if (Core.bDebug) {
                DebugLog.log("receiveObjectChange: index=" + int8 + " is invalid x,y,z=" + int5 + "," + int6 + "," + int7);
            }
        }
    }

    public static void sendClientCommand(IsoPlayer isoPlayer, String string0, String string1, KahluaTable kahluaTable) {
        ByteBufferWriter byteBufferWriter = connection.startPacket();
        PacketTypes.PacketType.ClientCommand.doPacket(byteBufferWriter);
        byteBufferWriter.putByte((byte)(isoPlayer != null ? isoPlayer.PlayerIndex : -1));
        byteBufferWriter.putUTF(string0);
        byteBufferWriter.putUTF(string1);
        if (kahluaTable != null && !kahluaTable.isEmpty()) {
            byteBufferWriter.putByte((byte)1);

            try {
                KahluaTableIterator kahluaTableIterator = kahluaTable.iterator();

                while (kahluaTableIterator.advance()) {
                    if (!TableNetworkUtils.canSave(kahluaTableIterator.getKey(), kahluaTableIterator.getValue())) {
                        DebugLog.log("ERROR: sendClientCommand: can't save key,value=" + kahluaTableIterator.getKey() + "," + kahluaTableIterator.getValue());
                    }
                }

                TableNetworkUtils.save(kahluaTable, byteBufferWriter.bb);
            } catch (IOException iOException) {
                iOException.printStackTrace();
            }
        } else {
            byteBufferWriter.putByte((byte)0);
        }

        connection.endPacketImmediate();
    }

    private static void receiveServerCommand(ByteBuffer byteBuffer) {
        String string0 = zombie.GameWindow.ReadString(byteBuffer);
        String string1 = zombie.GameWindow.ReadString(byteBuffer);
        boolean _boolean = byteBuffer.get() == 1;
        KahluaTable kahluaTable = null;
        if (_boolean) {
            kahluaTable = LuaManager.platform.newTable();

            try {
                TableNetworkUtils.load(kahluaTable, byteBuffer);
            } catch (Exception exception) {
                exception.printStackTrace();
                return;
            }
        }

        LuaEventManager.triggerEvent("OnServerCommand", string0, string1, kahluaTable);
    }

    public static void Reset() {
        for (ZomboidNetData zomboidNetData : MainLoopNetData) {
            ZomboidNetDataPool.instance.discard(zomboidNetData);
        }

        MainLoopNetData.clear();
    }

    private static final class UdpEngineClient extends UdpEngine {
        @Override
        public void Send(ByteBuffer byteBuffer) {
            SinglePlayerServer.udpEngine.Receive(byteBuffer);
        }

        @Override
        public void Receive(ByteBuffer byteBuffer) {
            int _int = byteBuffer.get() & 255;
            short _short = byteBuffer.getShort();
            SinglePlayerClient.addIncoming(_short, byteBuffer);
        }
    }
}
